package com.xiaolin.controller;

import com.xiaolin.anno.LoginToken;
import com.xiaolin.pojo.User;
import com.xiaolin.pojo.vo.BaseResult;
import com.xiaolin.pojo.vo.LoginResult;
import com.xiaolin.service.UserService;
import com.xiaolin.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 用户控制器
 *
 * @author XiaoLin
 * @date 2019/2/22 20:26
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 登陆
     */
    @PostMapping("/login")
    @LoginToken
    public ResponseEntity<BaseResult> login(@RequestBody User user) {
        try {

            //密码加密
            user.setPassword(SHA256Util.getSHA256(user.getPassword()));

            //登陆
            User u = userService.login(user);
            if (u == null) {
                return ResponseEntity.ok(new BaseResult(1, "密码错误或用户名不存在!"));
            }
            //生成JWT
            String jwt = JwtUtil.createJWT(18000000, u);
            //填充返回对象
            LoginResult loginResult = new LoginResult(0, "登陆成功", jwt, u.getUid());
            return ResponseEntity.ok(loginResult);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseEntity.ok(new BaseResult(1, "密码错误或用户名不存在!"));
    }

    /**
     * 获取用户头像
     */
    @GetMapping("/getUimage")
    @LoginToken
    public ResponseEntity<BaseResult> getUimage(String uname) {
        try {
            //通过uname查询头像
            String imgUrl = userService.findUimage(uname);
            if (imgUrl == null || imgUrl.length() == 0) {
                return ResponseEntity.ok(new BaseResult(1, "找不到头像!"));
            }
            return ResponseEntity.ok(new BaseResult(0, "", imgUrl));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseEntity.ok(new BaseResult(1, "获取出错!"));
    }

    /**
     * 通过token获取用户信息
     */
    @GetMapping("/getUserInfo")
    public ResponseEntity<BaseResult> getUserInfo(HttpServletRequest request) {
        try {
            //获取请求作用域中的user
            User u = (User) request.getAttribute("user");
            return ResponseEntity.ok(new BaseResult(0, "用户信息获取成功!", u));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ResponseEntity.ok(new BaseResult(1, "用户信息获取失败!"));
    }

    /**
     * 获取推荐好友
     */
    @GetMapping("/getRecoList")
    public ResponseEntity<BaseResult> getRecoList(Integer page, Integer size, String username, HttpServletRequest request) {
        try {
            String uid = (String) request.getAttribute("userId");
            List<User> recoList = userService.getRecoList(page, size, username, uid);
            return ResponseEntity.ok(new BaseResult(0, "推荐好友获取成功!", recoList));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ResponseEntity.ok(new BaseResult(1, "推荐好友获取失败!"));
    }

    /**
     * 注册
     */
    @PostMapping("/register/{code}")
    @LoginToken
    public ResponseEntity<BaseResult> register(@RequestBody User user, @PathVariable("code") String code) {
        try {

            String phoneCode = redisTemplate.opsForValue().get("phoneCode-" + user.getPhone());

            if (code == null || !code.equals(phoneCode)) {
                return ResponseEntity.ok(new BaseResult(1, "手机验证码错误或已过期!"));
            }

            // TODO 校验
            boolean boo = userService.existsName(user.getUsername());
            if (boo) {
                return ResponseEntity.ok(new BaseResult(1, "用户名已存在!"));
            }

            //密码加密
            user.setPassword(SHA256Util.getSHA256(user.getPassword()));
            //注册时间
            user.setRegisetrDate(new Date());
            user.setMyinfo("这个家伙很懒,什么都没留下!");
            user.setState(0);
            user.setNickName(user.getUsername());
            //默认头像
            user.setUimage(CommonData.imgServerUrl + "/uimage/qq.png");
            //保存数据库
            userService.insert(user);
            return ResponseEntity.ok(new BaseResult(0, "注册成功!"));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ResponseEntity.ok(new BaseResult(1, "注册失败!"));
    }

    /**
     * 判断用户名是否存在
     */
    @GetMapping("/existsName")
    @LoginToken
    public ResponseEntity<BaseResult> existsName(String username) {
        try {
            boolean boo = userService.existsName(username);
            if (boo) {
                return ResponseEntity.ok(new BaseResult(1, "用户名已存在!"));
            }
            return ResponseEntity.ok(new BaseResult(0, "用户名可用!"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseEntity.ok(new BaseResult(1, "系统出错,请刷新再请求!"));
    }

    /**
     * redis模板类
     */
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 获取验证码
     */
    @GetMapping("/getCode")
    @LoginToken
    public void getCode(HttpServletResponse response, String phone) throws IOException {
        // 设置响应的类型格式为图片格式
        response.setContentType("image/jpeg");
        //禁止图像缓存。
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);


        CreateImageCode vCode = new CreateImageCode(110, 34, 5, 10);

        //把图片验证码保存到rides中
        redisTemplate.opsForValue().set("imgCode-" + phone, vCode.getCode(), 5, TimeUnit.MINUTES);

        vCode.write(response.getOutputStream());
    }

    /**
     * 发送手机验证码
     */
    @GetMapping("/getPhoneCode")
    @LoginToken
    public ResponseEntity<BaseResult> getPhoneCode(String code, String phone) {
        try {
            System.out.println(code + ":" + phone);
            if (phone == null || phone.length() != 11 || code == null) {
                return ResponseEntity.ok(new BaseResult(1, "验证码或手机格式不准确!"));
            }
            //获得rides中的图片验证码
            String s = redisTemplate.opsForValue().get("imgCode-" + phone);
            if (!code.equalsIgnoreCase(s)) {
                return ResponseEntity.ok(new BaseResult(1, "图片验证码错误!"));
            }

            //获取上次手机验证码发送时间
            String t = redisTemplate.opsForValue().get("phoneTime-" + phone);

            if (t != null) {
                return ResponseEntity.ok(new BaseResult(1, "请稍后再发送验证码!"));
            }

            //获取随机6位验证码
            String phoneCode = GetRandomCodeUtil.getCode();
            //保存到rides中
            redisTemplate.opsForValue().set("phoneCode-" + phone, phoneCode, 5, TimeUnit.MINUTES);
            //保存发送时间
            long l = System.currentTimeMillis();
            redisTemplate.opsForValue().set("phoneTime-" + phone, l + "", 1, TimeUnit.MINUTES);
            //发送短信
            SmsUtil.sendSms(phone, phoneCode);
            System.out.println(phone + "的手机验证码为: " + phoneCode);
            return ResponseEntity.ok(new BaseResult(0, "消息已发送!", l));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseEntity.ok(new BaseResult(1, "系统出错,请刷新再重试!"));
    }

    /**
     * 获取上次手机验证码发送时间
     */
    @GetMapping("/getSendTime")
    @LoginToken
    public ResponseEntity<BaseResult> getSendTime(String phone) {
        try {
            //获取上次手机验证码发送时间
            String t = redisTemplate.opsForValue().get("phoneTime-" + phone);

            if (t != null) {
                return ResponseEntity.ok(new BaseResult(0, "", t));
            }
            return ResponseEntity.ok(new BaseResult(1, ""));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseEntity.ok(new BaseResult(1, "无法获取!"));
    }

    /**
     * 更新信息,不带头像
     *
     * @param u
     * @param request
     * @return
     */
    @PostMapping("/updataUserInfo")
    public ResponseEntity<BaseResult> updataUserInfo(@RequestBody User u, HttpServletRequest request) {
        try {
            String uid = (String) request.getAttribute("userId");
            //只能修改这三个,防止用户恶意修改
            // TODO 校验信息
            User user = new User();
            user.setUid(uid);
            user.setNickName(u.getNickName());
            user.setMyinfo(u.getMyinfo());
            user.setEmail(u.getEmail());
            //更新数据
            userService.updata(user);
            u = userService.findUserInfo(u.getUid());
            return ResponseEntity.ok(new BaseResult(0, "更新成功!", u));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseEntity.ok(new BaseResult(1, "更新失败!"));
    }

    /**
     * 更新信息和头像
     */
    @PostMapping("/updataUserAndFile")
    public ResponseEntity<BaseResult> updataUserAndFile(@RequestParam("imgfile") MultipartFile file,
                                                        @RequestParam("nickName") String nickName,
                                                        @RequestParam("myinfo") String myinfo,
                                                        @RequestParam("email") String email, HttpServletRequest request) {
        try {


            String uid = (String) request.getAttribute("userId");
            String fileName = file.getOriginalFilename();
            //文件后缀名
            String suffix;
            if (fileName.lastIndexOf(".") != -1) {
                suffix = fileName.substring(+1);
            } else {
                suffix = null;
            }
            String path = "\\uimage\\uimage" + uid + "_" + System.currentTimeMillis() + (suffix == null ? "" : "." + suffix);
            //保存图片
            String imgName = CommonData.filePath + path;
            File file1 = new File(imgName);
            File fileParent = file1.getParentFile();
            if (!fileParent.exists()) {
                fileParent.mkdirs();
            }
            BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file1));
            out.write(file.getBytes());
            out.flush();
            out.close();

            //只能修改这三个,防止用户恶意修改
            // TODO 校验信息
            User u = new User();
            u.setNickName(nickName);
            u.setMyinfo(myinfo);
            u.setEmail(email);
            u.setUimage(CommonData.imgServerUrl + path);
            u.setUid(uid);
            userService.updata(u);
            u = userService.findUserInfo(u.getUid());
            return ResponseEntity.ok(new BaseResult(0, "更新成功!", u));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseEntity.ok(new BaseResult(1, "更新失败!"));
    }


}
